package com.example.bankseckill.controller;


import com.auth0.jwt.interfaces.DecodedJWT;
import com.example.bankseckill.pojo.BookingSeckill;
import com.example.bankseckill.pojo.User;
import com.example.bankseckill.pojo.vo.ProductVo;
import com.example.bankseckill.pojo.vo.RespBean;
import com.example.bankseckill.pojo.vo.RespBeanEnum;
import com.example.bankseckill.pojo.vo.UserInfoVo;
import com.example.bankseckill.service.IBookingSeckillService;
import com.example.bankseckill.service.ISeckillProductService;
import com.example.bankseckill.service.IUserService;
import com.example.bankseckill.utils.CreateAgeByIdentity;
import com.example.bankseckill.utils.FastDFSUtils;
import com.example.bankseckill.utils.MD5Util;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletRequest;
import javax.validation.Valid;
import java.util.Date;
import java.util.List;
import java.util.concurrent.TimeUnit;

/**
 * <p>
 *  前端控制器
 * </p>
 *
 * @author liyangjing
 * @since 2022-01-26
 */
@RestController
@RequestMapping("/bank/user")
@Api(tags = "用户模块")
@Slf4j
public class UserController {

    @Autowired
    private IUserService userService;
    @Autowired
    private RedisTemplate redisTemplate;

    @Autowired
    private ISeckillProductService seckillProductService;

    @Autowired
    private IBookingSeckillService bookingSeckillService;

    /**
     * 返回当前用户信息
     * @param user
     * @return
     */
    @ApiOperation(value = "返回用户信息")
    @RequestMapping(value = "/getinfo",method = RequestMethod.GET)
    public RespBean getUserInfo(User user){
        if(user==null){
            return RespBean.error(RespBeanEnum.TOKEN_EXPIRED);
        }
        return RespBean.success("欢迎您回来！",user);
    }

    /**
     * 修改当前用户信息
     * @param user
     * @param userInfoVo
     * @return
     */
    @ApiOperation(value = "修改当前用户信息")
    @RequestMapping(value = "/updateinfo",method = RequestMethod.PUT)
    public RespBean updateUserInfo(User user, @RequestBody @Valid UserInfoVo userInfoVo){
        log.info("修改用户信息{}",userInfoVo);
        //更新用户信息
        //身份证
        user.setIdentitycard(userInfoVo.getIdentitycard());
        //用户名
        user.setUsername(userInfoVo.getUsername());
        //电话
        user.setPhone(userInfoVo.getPhone());
        //邮箱
        user.setEmail(userInfoVo.getEmail());
        //根据身份证更新年龄
        user.setAge(CreateAgeByIdentity.getPersonAgeFromIdCard(userInfoVo.getIdentitycard()));
        boolean result = userService.updateById(user);
        if(result){
            //更新缓存
            redisTemplate.opsForValue().set("user:" + user.getId(),user,30, TimeUnit.MINUTES);
            return  RespBean.success("更新信息成功！");
        }
        return RespBean.success("更新信息失败！");
    }


    /**
     * 修改用户的头像
     * @param user
     * @param file
     * @return
     */
    @ApiOperation(value = "修改用户头像")
    @ApiImplicitParams({@ApiImplicitParam(name = "file", value = "头像", dataType = "MultipartFile")})
    @RequestMapping(value = "/avatar",method = RequestMethod.POST)
    public RespBean updateUserAvatar(User user, MultipartFile file){
        if(file==null){
            return RespBean.error(RespBeanEnum.FILE_EMPTY);
        }
        if(user==null){
            return RespBean.error(RespBeanEnum.KILL_LOGIN_ERROR);
        }
        //获取上传文件地址（利用fastdfutil）
        String[] fileabsolutePath = FastDFSUtils.upload(file);
        String url = FastDFSUtils.getTrackerUrl()+fileabsolutePath[0]+"/"+fileabsolutePath[1];
        return userService.updateUserAvatar(user,url);
    }

    /**
     * 修改密码 密码也要由前端md5加密一次
     * @param user
     * @param oldpassword 原密码
     * @param newPassword 新密码
     * @return
     */
    @ApiOperation(value = "修改密码")
    @RequestMapping(value = "/updatePassword",method = RequestMethod.PUT)
    public RespBean updatePassword(User user,String oldpassword,String newPassword){
        //第二次加密 获得原密码
        String password = MD5Util.formPassToDBpass(oldpassword, "1a2b3c4d");
        //与数据库比较
        User one = userService.getById(user.getId());
        if(one==null){
            return RespBean.error(RespBeanEnum.KILL_LOGIN_ERROR);
        }
        //若密码正确则更新
        if(one.getPassword().equals(password)) {
            one.setPassword(MD5Util.formPassToDBpass(newPassword, "1a2b3c4d"));
            userService.updateById(one);
            return RespBean.success("修改密码成功！");
        }else {
            return RespBean.error("原密码错误！");
        }
    }

    /**
     * 用户预约产品
     * @param user
     * @param SeckillProductId
     * @return
     */
    @ApiOperation(value = "预约秒杀产品")
    @RequestMapping(value = "/seckillproduct/booking",method = RequestMethod.POST)
    public RespBean bookingProduct(User user,String SeckillProductId){
        long id = Long.parseLong(SeckillProductId);
        ProductVo productVo = seckillProductService.findProductVoById(id);
        //若用户传入的seckillproduct Id 找不到
        if(productVo==null){
            return RespBean.error("没有此产品，预约失败！");
        }
        //若预约时间已过 活动开始时间小于当前时间
        if(productVo.getStartDate().before(new Date())){
            return RespBean.error("预约时间已过！下次请注意时间哟~");
        }
        //检查是否已经预约
        Boolean member = redisTemplate.opsForSet().isMember("bookingSecproduct:" + SeckillProductId, user.getId());
        if(member){
            return RespBean.error("您已经预约过了!");
        }
        //开始预约
        //redis插入数据
        redisTemplate.opsForSet().add("bookingSecproduct:" + SeckillProductId, user.getId());

        //更新持久层
        BookingSeckill bookingSeckill = new BookingSeckill();
        bookingSeckill.setUserId(user.getId());
        bookingSeckill.setSeckillproductId(new Long(SeckillProductId));
        bookingSeckill.setEndTime(productVo.getEndDate());
        bookingSeckill.setStartTime(productVo.getStartDate());
        //活动即将开始
        bookingSeckill.setStatus(0);
        //存入数据库
        boolean result = bookingSeckillService.save(bookingSeckill);
        if(result){
            return RespBean.success("预约成功！","预约成功！");
        }
        return RespBean.error("预约失败!");
    }

    /**
     * 返回用户秒杀预约记录
     * @param user
     * @return
     */
    @ApiOperation(value = "返回用户秒杀预约记录")
    @RequestMapping(value = "/seckillproduct/bookRecords",method = RequestMethod.POST)
    public RespBean getBookingRecords(User user){
        List<BookingSeckill> bookingSeckills = bookingSeckillService.findRecordsByUserId(user.getId());
        return RespBean.success(bookingSeckills);
    }

}
